package cheme.ProcessModel.Interpreter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import cheme.ProcessModel.IChild;
import cheme.ProcessModel.IModelElement;
import cheme.ProcessModel.ModelEnv;
import cheme.ProcessModel.ParsingUtil;
import cheme.ProcessModel.ProcessModel;
import cheme.ProcessModel.SolvabilityStatus;
import cheme.ProcessModel.Equations.Equation;
import cheme.ProcessModel.Equations.EquationList;
import cheme.ProcessModel.Equations.Equations;
import cheme.ProcessModel.Interpreter.IRule.RuleResult;
import cheme.ProcessModel.ProcessUnits.ProcessUnit;
import cheme.ProcessModel.ProcessUnits.Streams.Stream;
import cheme.ProcessModel.ProcessUnits.Streams.Tags.IGeneralTagComponent;
import cheme.ProcessModel.ProcessUnits.Streams.Tags.ITagComponent;
import cheme.ProcessModel.ProcessUnits.Streams.Tags.OverallTagComponent;
import cheme.ProcessModel.ProcessUnits.Streams.Tags.Tag;
import cheme.ProcessModel.ProcessUnits.Streams.Tags.TagComponentList;
import cheme.ProcessModel.Table.Field;
import cheme.ProcessModel.Table.IRow;


/*
 * This class implments the equation independece rule
 * Here we first get the count and components of the diagram that have unknown quantity
 * Then we check and get the count of linear and quadratic equations
 * Finally we check if there are sufficient euations to solve for all the unknowns
 * Also that every unknown is represented in atleast one of the equations
 */

public abstract class EquationIndependenceRule implements IRule
{
	
	private int iUnknownCount = 0;
	String strLast = null;
	boolean bLastOperator = false;
	private ArrayList<String>UnkownComponentsList = new ArrayList<String>();
	//List<String>UnkownComponentsList;
	private boolean bQuadratic;
	private int iQudratic;
	private int iLinear;	
	private int iEquationCount;
	private String[] unknownarray ;   
	private double[][]Coeffmatrix;
	private String[] anArray;
	private int iUnknownItemCount;
	protected Interpreter interpreter = null;
	private Equation equation;

	//protected abstract boolean EquationIndependenceCheck(int iUnknownCount,int iLinear,int iQudratic);
	protected abstract boolean EquationIndependenceCheck(int iUnknownCount,int iEquationCount);
	protected abstract RuleResult tokenCheck(Field equationToken);
	
	public RuleResult applyTo(IModelElement object)	{
		Resetvaraibles();
		ProcessModel pm = null;
		Equations eqObject = null;
		boolean bParser = false;		
		
		if(!(object instanceof ProcessModel))
		{
			pm = (ProcessModel)object.getRoot();			
		}
		else{
			pm = (ProcessModel)object;
		}
		getUnknownCount(pm);
		
		Iterator<IChild> eqitr = null;
		
		//if(!(object instanceof Equation))
		//{
		Iterator<IChild> itr = pm.iterator();
		eqObject = (Equations)itr.next();// first element is the equation	
		eqitr = eqObject.iterator();
		eqitr.next(); // skip the first element in the list. it is equation palette
		//}
		EquationList eqlist = (EquationList) eqitr.next();
		SolvabilityStatus statusItem = (SolvabilityStatus)eqitr.next();		
		
		RuleResult result = new IRule.Success((IModelElement)statusItem);
		
			
		
		if(eqObject instanceof Equations)
		{
			//EquationList eqlist  =  (EquationList) eqObject.getParent();			
			
			Iterator<IRow> Eqlistitr = eqlist.getChildren().iterator();
			int eqCount = 0;
			
			while(Eqlistitr.hasNext())
			{
				bQuadratic = false; // Reset the variable
				Equation eq = (Equation) Eqlistitr.next();
				
				//result = new IRule.Success((IModelElement)eq);
				
				if(!eq.isInitial()) // Also check for, if the equation is correct/complete
				{
					eqCount++;//Keeps track of total number of equations
					
					/// Work done to add updater
					interpreter = ModelEnv.getInstanceFor(eq).getInterpreter();
					Iterator<Field> iterator =  eq.iterator();
					Field field = null;	
					field = iterator.next();
					while( !(field.getText().isEmpty())&& iterator.hasNext())
					{
						result = tokenCheck(field);
						field = iterator.next();
					}
					
					/// Work done to add updater ends
					
					RuleResult resulttemp = isEquationComplete(eq); 					
					
					if(resulttemp instanceof IRule.Success)
					{
						if(getParseResult(eq))
						{
							bParser = true;
							// Get the equation type, Only if equation is parsed correctly and passes all the rule checks
							getEquationType(eq);
							if(bQuadratic)
							{
								iQudratic++;
							}
							else{
								iLinear++;
							}
						}
					}					
					/*else
					{
						statusItem.setMessage("You do NOT have enough valid equations to solve for all the unknowns." );
						statusItem.setColor("red");
						result = new IRule.Failure((IModelElement)statusItem, "You do NOT have enough equations to solve for all the unknowns.");
					}*/
					// PA: Commented this
					// Because whenever it got first incomplete equation, it was returning the error 
					// without going through all the equations in the system.
					// if equation is not complete
					//else
					//{
						//statusItem.setMessage("You do NOT have enough valid equations to solve for all the unknowns.\n You have " + iEquationCount + " valid equation(s) and " + iUnknownCount + " unknown(s).\n  The number of independent equations and the number of unknowns should be the same.");
						//statusItem.setColor("red");
						//return result;
					//}
				}
			}
			// If there are 0 equations in the system, do nothing
			if(eqCount == 0)
			{
				return result;
			}
			
		}
		// If user has created an equation but there are no unknowns in the system
		if(iUnknownCount < 1){
			statusItem.setMessage("There are no unknowns in this model.");
			statusItem.setColor("green");
			return result;
		}
		// Working starts from here
		statusItem.setMessage("working");
		statusItem.setColor("red");
		
		if(0 < iQudratic){
			statusItem.setMessage("You have specified Qudratic equation(s).\n Quadratic equation are not yet supported by the system.\n Please modify the equation to make it linear.");
			statusItem.setColor("red");
			result = new IRule.Failure((IModelElement)statusItem, "You have specified Qudratic equation(s).\n Quadratic equation are not yet supported by the system.\n Please modify the equation to make it linear."); 
			
		}
		// iLinear - Total linear equations
		// iEquationCount - Total equations having atleast one of the unknown element
		else if(iUnknownCount < iLinear){
			statusItem.setMessage("You have overspecified the model.\n You have" + iUnknownCount + " unknown(s) and " + iLinear + " equation(s). \n  The number of independent equations and the number of unknowns should be the same.");
			statusItem.setColor("red");
			result = new IRule.Failure((IModelElement)statusItem, "You have overspecified the model.\n You have" + iUnknownCount + " unknown(s) and " + iLinear + " equation(s). \n  The number of independent equations and the number of unknowns should be the same.");
			
		}
		//if(!EquationIndependenceCheck(iUnknownCount, iLinear, iQudratic))
		else if(!EquationIndependenceCheck(iUnknownCount,iLinear))// iEquationCount))	
		{
			statusItem.setMessage("You do NOT have enough equations to solve for all the unknowns.\n You have " + iEquationCount + " valid equation(s) and " + iUnknownCount + " unknown(s).\n  The number of independent equations and the number of unknowns should be the same.");
			statusItem.setColor("red");
			result = new IRule.Failure((IModelElement)statusItem, "You do NOT have enough equations to solve for all the unknowns.\n You have " + iEquationCount + " valid equation(s) and " + iUnknownCount + " unknown(s).\n  The number of independent equations and the number of unknowns should be the same."); // you have x equations and y unknowns			
		}
		// If there are sufficient number of equations for all the unknowns,
		// then check if each unknown component is represented in the equations.
		else if(bParser && !allUnknownsPresentinTheEquations(eqlist))
		{
				//result = new IRule.Failure((IModelElement)eqObject, "The following unknowns are not present in the equation: " + iUnknownCount);// list the unknowns not present.
				String strList = "";
				for (int i = 0; i < iUnknownItemCount;i++){
					strList += anArray[i];
					strList += ",";
				}
				statusItem.setMessage("The following unknowns are not present in the equation:\n" + strList);
				statusItem.setColor("red");
				result = new IRule.Failure((IModelElement)statusItem, "The following unknowns are not present in the equation:\n" + strList);
		}
		else{
			if (!isEquationSolvable(eqlist)){
				// if Equation is not solvable, modify the message
				statusItem.setMessage("The set of equations that you have created is NOT solvable.\nThe equations that you have written are not independent of each other.");
				statusItem.setColor("red");
				result = new IRule.Failure((IModelElement)statusItem, "The set of equations that you have created is NOT solvable.\nThe equations that you have written are not independent of each other.");
				// 
			}
			else{
				//result = new IRule.Warning((IModelElement)eqObject, "Congratulations! The set of equations that you have created is solvable.");
				statusItem.setMessage("Congratulations! The set of equations that you have created is solvable.");
				statusItem.setColor("green");
				result = new IRule.Success((IModelElement)statusItem);
				
			}
		}
		
		return result;
	}

	/********** Functions for Solvability test Starts here ****************/
	
	private boolean isEquationSolvable(EquationList eqlist) {
		
		Iterator<IRow> Eqlistitr = eqlist.getChildren().iterator();
		Coeffmatrix = new double[iUnknownCount][iUnknownCount];// if 3 unknowns then 3x3 matrix is required
		// intialize the matrix with zero
		for(int i =0;i<iUnknownCount;i++){
			for(int j=0;j<iUnknownCount;j++){
				Coeffmatrix[i][j] = 0;
			}
		}
		
		while(Eqlistitr.hasNext())
		{
			int ieqcount = 0; // denotes the row in the matrix
			while(Eqlistitr.hasNext())
			{
				Equation eq = (Equation) Eqlistitr.next();
				if(!eq.isInitial()){
					populateMatrix(eq,ieqcount);	
					ieqcount++;
				}
			}
		}
		
		return (getSolvability());
	}

	private boolean getSolvability() {
		
		//Matrix inputJama = new Matrix(Coeffmatrix);  
		double det = 1;
		if( iUnknownCount > 1){
			det = Calculatedeterminant(Coeffmatrix,iUnknownCount);
		}
		
		if(det != 0) return true;
		
		return false;
	}

	private double Calculatedeterminant(double dmatrix[][],int Orderofmatrix) {
		// Whatever is the unknown count will be the order of the matrix.
		//int Orderofmatrix = iUnknownCount;
		double[][] c = new double[iUnknownCount][iUnknownCount];
		double sum = 0;int j = 0, i;
		if(Orderofmatrix == 2)
		  {                                        //BASE CONDITION
			sum = dmatrix[0][0]*dmatrix[1][1] - dmatrix[0][1]*dmatrix[1][0];
			return sum;
		  }
		
		for(int p=0;p<Orderofmatrix;p++)
		 {
		  int h = 0,k = 0;
		  for(i=1;i<Orderofmatrix;i++)
		  {
			for( j=0;j<Orderofmatrix;j++)
			{
			 if(j==p)
			  continue;
			 c[h][k] = dmatrix[i][j];
			 k++;
			 if(k == Orderofmatrix-1)
			  {
				 h++;
				 k = 0;
			  }

			}
		  }

		  sum = sum + dmatrix[0][p]*Math.pow(-1,p)*Calculatedeterminant(c,Orderofmatrix-1);
		 }
		 return sum;

		
	}

	// Populate the Co efficent Matrix for unknown elements
	private void populateMatrix(Equation eq, int ieqcount) {
		
		Float ilastCoeff = Float.valueOf(0.0f);// Integer.valueOf(0);
		String sLastelement = "";
		String sLastoperator = "";
		int index = 0;
		Iterator<Field> fIterator =  eq.iterator();
		String token = "";
		
		while(fIterator.hasNext() ){
			Field field = fIterator.next();
			token = field.getText().trim();
			
			if (!token.isEmpty())
			{
				if(ParsingUtil.isOperator(token) )
				{
					if(token.equals("*")){
						sLastoperator = token;
					}
					// e.g 6x+y = 100. Coeff of y is 1.
					else if(!sLastelement.isEmpty()){
						// This means that co eff is 1
						// store the coeeficient of the unknown
						storeValue(index,1.0f,ieqcount);
						// reset the variables
						sLastelement = "";
						sLastoperator = "";
						ilastCoeff = 0.0f;
					}
				}
				else if(ParsingUtil.isNumber(token)|| isTokenknown(token))
				{
					float val = 0.0f;
					
					if(!ParsingUtil.isNumber(token)){
						// token is not a number, so get this known element's value
						val = getvalueOfElement(eq,token);
						
					}						
					else{
						// This token is a number
						val = Float.parseFloat(token); 
					}
					// Store the value of possible co efficient
					ilastCoeff = Float.valueOf(val);//Integer.valueOf(val);
					
					// e.g M1 * M2 = 100, where M2 is known,
					// then store the value of M2 as co efficient of M1 OR
					// M1 * 6 = M2, store 6 as coefficient of M1
					if(sLastoperator.equals("*")&& !sLastelement.isEmpty()){
						// store the coeeficient of the unknown
						storeValue(index,ilastCoeff,ieqcount);
						// reset the variables
						sLastelement = "";
						sLastoperator = "";
						ilastCoeff = 0.0f;
					}
				}
				// this means that token is not a operator, not a number and is not known
				// That is this token is an unknown element
				else{
					index = getUnkownIndex(token);
					if (index < iUnknownCount)
					{
						// PA : Change to fix x*y =100 issue						
						// if last element in not empty and it is also an unknown quantity then						
						// update its value in the matrix.
						// e.g x * y = 100. current token is y and last element is x.
						if(!sLastelement.isEmpty()&& !(isTokenknown(sLastelement)))
						{
							int oldIndex = getUnkownIndex(sLastelement);
							storeValue(oldIndex,1.0f,ieqcount);
							// reset the variables
							sLastelement = "";
							sLastoperator = "";
							ilastCoeff = 0.0f;
						}
						// PA : Change Ends
						// store this token, as this is an unknown element
						sLastelement = token;
					}
					// e.g 6 * M1 or
					// M1 * M2, where M2 is known,
					if(sLastoperator.equals("*")&& ilastCoeff > 0)
					{
						// store the coeeficient of the unknown
						storeValue(index,ilastCoeff,ieqcount);
						// reset the variables
						sLastelement = "";
						sLastoperator = "";
						ilastCoeff = 0.0f;
					}
				}
			}
		}
		// Spl case for the last element in the equation
		
		// e.g 100 = x+y. In this case we have to enter the coeff of y.
		if(!sLastelement.isEmpty()){
			// This means that co eff is 1
			// store the coeeficient of the unknown
			storeValue(index,1.0f,ieqcount);
			// reset the variables
			sLastelement = "";
			sLastoperator = "";
			ilastCoeff = 0.0f;
		}
	
		
	}

	// This functions gets the value of the known element
	private float getvalueOfElement(Equation eq, String token) {
		Interpreter interpreter = ModelEnv.getInstanceFor(eq).getInterpreter();
		ModelElementData modelData = interpreter.getModelData(token);
		ITagComponent referencedTagComponent = null;
		if(null != modelData && modelData.getModel() instanceof ITagComponent)
		{
			referencedTagComponent = (ITagComponent)modelData.getModel();
			String strVal = referencedTagComponent.getQuantity();
			if(!(strVal.equals("")|| strVal.equals("?")))
			{
				float val = Float.parseFloat(strVal);
				String strUnits = referencedTagComponent.getUnits();
				if(strUnits.equals("%")){
					val = val /100.0f; // Convert % into value
				}			
				return val;
			}
		}
		return 0.0f;
	}

	// To find whether the token is known or unknown element
	// True - if element is Known
	private boolean isTokenknown(String token) {
		int index = 0;	
		boolean bRet= true;
		while(index < iUnknownCount){
			if(token.equals(unknownarray[index])){
				bRet = false;
				return bRet;
			}
			index++;
		}
		return bRet;
	}

	// This function will store the value in the matrix form.
	private void storeValue(int index, Float ilastCoeff, int ieqcount) {
		if(ieqcount < iUnknownCount)
		{
			Coeffmatrix[ieqcount][index] = ilastCoeff.floatValue();
		}
		/*int row = 0;
		// if 3 unknowns, then matrix index will be 0,1,2
		while (row < iUnknownCount)
		{
			if(Coeffmatrix[row][index]== 0){
				Coeffmatrix[ieqcount][index] = ilastCoeff.floatValue();//.intValue();
				break;
			}
			row++;
		}*/
		
	}

	// to get the index of the unknown element from the array
	private int getUnkownIndex(String token) {
		int index = 0;
		while(index < iUnknownCount){
			if(token.equals(unknownarray[index]))
				return index;
			
			index++;
		}
		return index;
	}
	
	/********** Functions for Solvability test Ends here ****************/

	// This function return false if an unknown is not present in any of the equations. 
	private boolean allUnknownsPresentinTheEquations(EquationList eqlist) {
		
		boolean bResult = false;
		iUnknownItemCount = 0;
		anArray = new String[iUnknownCount];
		Iterator<String> unkownComponentitr = UnkownComponentsList.iterator();
		while(unkownComponentitr.hasNext())
		{
			String strUnknownCmpt = unkownComponentitr.next();
			Iterator<IRow> Eqlistitr = eqlist.getChildren().iterator();
			bResult = false; // reset the Varaible
			while(Eqlistitr.hasNext())
			{
				Equation eq = (Equation) Eqlistitr.next();
				if(!eq.isInitial()){
				
					Iterator<Field> fIterator =  eq.iterator();
					while(fIterator.hasNext() ){
						Field field = fIterator.next();
						String token = field.getText().trim();
						if (!token.isEmpty()&& !ParsingUtil.isOperator(token) && !ParsingUtil.isNumber(token) )
						{
							if(token.equalsIgnoreCase(strUnknownCmpt))
							{
								bResult = true; // Unknown Found in the equation list
								break;
							}
						}
					}
				}				
			}
			if(!bResult){
				anArray[iUnknownItemCount]= strUnknownCmpt;
				iUnknownItemCount++;
				//break; // This means that last un known component is not present in the equations
			}
		}
		if(iUnknownItemCount > 0)
			bResult = false;
		else
			bResult = true;
		
		return bResult;
	}

	// This function will check that the given equation
	// satisfies all other rules successfuly
	private RuleResult isEquationComplete(Equation eq) {
		boolean bResult = false;
		//RuleResult result =  PostParseRules.equationNonEmptyText.applyTo(eq) ;		
		//if (result instanceof IRule.Success )
		//{
			RuleResult result =  PostParseRules.equationIsCorrect.applyTo(eq);	
		
			if (result instanceof IRule.Success )
			{
				bResult = true;
				/*result = PostParseRules.unitAgreementEx.applyTo(eq);				
				if (result instanceof IRule.Success )
				{
					bResult = true;
				}*/
			}
		//}
		return result;
	}

	// This function checks that the given equation is parsed correctly by the parser
	private boolean  getParseResult (IModelElement eq) {		
		
		Interpreter interpreter = ModelEnv.getInstanceFor(eq).getInterpreter();
		interpreter.setModelElement(eq);
		interpreter.setInterpretationHalted(false);
		interpreter.setParseResult(interpreter.parse());
		if(interpreter.getParseResult() == null && interpreter.getInterpretationHalted())
			return false;
		else
			return true;
	}

	private void Resetvaraibles() {
		// TODO Auto-generated method stub
		iUnknownCount = 0;
		iEquationCount = 0;
		strLast = null;
		bLastOperator = false;
		UnkownComponentsList.clear();
		bQuadratic = false;
		iQudratic = 0;
		iLinear = 0;
	}

	private void getEquationType(Equation eq) {			
		Iterator<Field> iterator =  eq.iterator();
		Field field = null;	
		while(iterator.hasNext())
		{
			field = iterator.next();	
			
			// To check if this equation has atleast one of the unknowns
			String token = field.getText().trim();	
			if(!ParsingUtil.isOperator(token) && !ParsingUtil.isNumber(token))
			{
				Iterator<String> unkownComponentitr = UnkownComponentsList.iterator();
				while(unkownComponentitr.hasNext())
				{
					String UnknownItem = unkownComponentitr.next();				
					if(UnknownItem.equalsIgnoreCase(token))
					{
						// if this equation has atleast one of the unknowns
						iEquationCount++;
						return;
					}
				}
			
			}			
			//		 To check if this equation has atleast one of the unknowns - Ends
			
			//Checktoken(field); // can be removed as Linear and quadratic count is not required
			if(bQuadratic) break;
		}
	}

	// This method will check the currect token of the equation.
	// This is the check if an unknown qty is mul/div. by unknown qty.
	private void Checktoken(Field field) {
		String token = field.getText().trim();		
		if(!token.isEmpty())
		{
			if(!ParsingUtil.isOperator(token) && !ParsingUtil.isNumber(token))
			{
				if(!bLastOperator){
					// Store this label.
					strLast = token;
				}
				else
				{
					// Check the last stored label and this. If  both are unknown then Quadratic Equation
					// Reset the bLastOperator to false.
					boolean bFirstComponent = false;
					boolean bSecondComponent = false;
					// iterator of the unknown components list.
					Iterator<String> unkownComponentitr = UnkownComponentsList.iterator();
					while(unkownComponentitr.hasNext())
					{
						String ListItem = unkownComponentitr.next();
						if(strLast.equals(ListItem)){
							bFirstComponent = true;
							break;
						}
					}
					unkownComponentitr = UnkownComponentsList.iterator();
					while(unkownComponentitr.hasNext())
					{
						String ListItem = unkownComponentitr.next();
						if(token.equals(ListItem)){
							bSecondComponent = true;
							break;
						}
					}
					if(bFirstComponent && bSecondComponent){
						bQuadratic = true;
					}
					bLastOperator = false;
				}// Else ends
				
			}// if Ends
			
			else 
			{
				if(token.equals("*")|| token.equals("/"))
					bLastOperator = true;
			}
		}
		
	}

	// This method calls getCount method to get the count of total number of Unknowns in the diagram
	private void getUnknownCount(ProcessModel pm) {
		Iterator<IChild> itr = pm.iterator();
		//itr.next();// skip first element
		//itr.next();// skip second element = PA: Hello Model
		IChild child = itr.next();
		
		// skip the list to the first process unit
		while(( child instanceof ProcessUnit) == false )
		{
			child = itr.next();
		}

		ProcessUnit pu = null;
		pu = (ProcessUnit) child;
		while (null != pu)
		{
			Iterator<IChild> Streamitr = pu.getInStreams().iterator();
			getCount(Streamitr);
			if(itr.hasNext())
				pu = (ProcessUnit) itr.next();
			else
				pu = null;
		}
		
		/*while(itr.hasNext())
		{
			pu = (ProcessUnit) itr.next();
			if(null != pu){
				Iterator<IChild> Streamitr = pu.getInStreams().iterator();
				getCount(Streamitr);
			}
		}*/
		
		// get the unknowns of the last Unit. It is possible that last streams are not connected at both the ends
		/*if(null != pu){
			Iterator<IChild> Streamitr = pu.getOutStreams().iterator();
			if(null != Streamitr)
				getCount(Streamitr);
		}*/
	}
 
	// This method gets the count of the unknown components in the diagram and also adds the unknown elements
	// in the list.
	private void getCount(Iterator<IChild> Streamitr) {
				
		while(Streamitr.hasNext())
		{
			Stream mu = (Stream)Streamitr.next();
			Iterator<Tag> StreamChilditr = mu.iterator();			
			int i = 0;
			if(StreamChilditr!= null)
			{
				Tag tu = (Tag)StreamChilditr.next();							
				
				Iterator<IChild> Tagiterator = tu.iterator(); // For checking the type
				Iterator<IChild> Tempiterator = tu.iterator(); // For getting the value
				while(Tagiterator.hasNext())
				{
					if(Tagiterator.next() instanceof OverallTagComponent)
					{
						ITagComponent childComponent = (ITagComponent) Tempiterator.next();
						String qty = childComponent.getQuantity();
						if(qty.equals("?")|| qty.equals(""))
						{
							iUnknownCount++;
							UnkownComponentsList.add(childComponent.getLabel());
						}
						
					}
					else
					{
						TagComponentList subComponent = (TagComponentList)Tempiterator.next();
						Iterator<IGeneralTagComponent> Listiterator = subComponent.getChildren().iterator();
						ITagComponent childComponent = null;
						while(Listiterator.hasNext())
						{				
							childComponent = (ITagComponent)Listiterator.next();
							
							if(!childComponent.isInitial())
							{
								String qty = childComponent.getQuantity();
								if(qty.equals("?") || qty.equals(""))
								{
									iUnknownCount++;
									String Componentname = childComponent.getLabel();
									UnkownComponentsList.add(Componentname);		
								}
							}
													
						}
					}
					
				}
			}
			// Allocate memry to the array
			unknownarray = new String[iUnknownCount];
			Iterator<String> unkownComponentitr = UnkownComponentsList.iterator();
			while(unkownComponentitr.hasNext())
			{
				String ListItem = unkownComponentitr.next();
				// Add the unknown item to the array
				unknownarray[i] = ListItem;
				i++;
			}
			
		}
	} // get count method ends
	
	public void setEquation(Equation equation)
	{
		this.equation = equation;
	}

	/**
	 * @return the equation
	 */
	public Equation getEquation()
	{
		return equation;
	}

};
